Skip to content

Add Hapi.js middleware#2

Open
Lasalot wants to merge 2 commits intomainfrom
add-prerender-hapi
Open

Add Hapi.js middleware#2
Lasalot wants to merge 2 commits intomainfrom
add-prerender-hapi

Conversation

@Lasalot
Copy link
Copy Markdown
Collaborator

@Lasalot Lasalot commented Apr 21, 2026

Initial implementation of the Prerender.io integration for hapi.

Comment thread index.js
try {
const apiUrl = buildApiUrl(request, settings);
const prerendered = await fetchPrerendered(apiUrl, request, settings);
settings.afterRender(request, prerendered);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd await this one as well and highlight that it should be a promise like for beforeRender.

Comment thread test/smoke.test.js
Comment on lines +13 to +19
function mockFetch(status = 200, body = PRERENDERED_HTML) {
global.fetch = async () => ({
status,
headers: new Headers({ 'content-type': 'text/html' }),
text: async () => body
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has no teardown/restore between tests. If a previous test leaves a broken mock, the next test inherits it silently.

Comment thread index.js
Comment on lines +71 to +77
function buildResponse(h, prerendered) {
const response = h.response(prerendered.body).code(prerendered.status).takeover();
for (const [key, value] of prerendered.headers.entries()) {
response.header(key, value);
}
return response;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we skip forwarding headers that are managed by Hapi internally (e.g., content-length, content-encoding)? Apparently other integrations (Express middleware) typically do filter these — worth checking if this causes issues in practice with Hapi v21

something like

const SKIP_HEADERS = new Set(['content-encoding', 'content-length', 'transfer-encoding', 'connection']);
  for (const [key, value] of prerendered.headers.entries()) {
    if (!SKIP_HEADERS.has(key.toLowerCase())) response.header(key, value);
  }

Comment thread package.json
Comment on lines +20 to +21
"url": "git://github.com/prerender/integrations",
"directory": "prerender-hapi"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm shouldn't it be prerender/hapi?

Comment thread index.js
'.dmg', '.iso', '.flv', '.m4v', '.torrent', '.ttf', '.woff', '.svg'
];

internals.defaults = {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could add jsdoc, it's just comments but helps as a very light type checker

/**
   * @typedef {{ status: number, headers: Headers, body: string }} PrerenderResponse
   */

  /**
   * @typedef {Object} PrerenderOptions
   * @property {string} [token]
   * @property {string} [serviceUrl]
   * @property {string|null} [protocol]
   * @property {(request: import('@hapi/hapi').Request) => Promise<PrerenderResponse|null>} [beforeRender]
   * @property {(request: import('@hapi/hapi').Request, response: PrerenderResponse) => void|Promise<void>} [afterRender]
   */

Also as suggested later I'd move the afterRender as a Promise

Comment thread index.js
return `${base}${protocol}://${request.headers.host}${pathname}${search}`;
}

async function fetchPrerendered(apiUrl, request, settings) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jsdoc

  /**
   * @returns {Promise<PrerenderResponse>}
   */

Comment thread index.js

exports.plugin = {
pkg: require('./package.json'),
async register(server, options) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jsdoc

  /**
   * @param {PrerenderOptions} options
   */

Comment thread index.js
Comment on lines +62 to +64
if (settings.token) {
headers['X-Prerender-Token'] = settings.token;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can log a warning here, could be useful to debug for the client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants